package info.bond.rp.experiments;


public class SpaceCoordinatesGenerator {
	
	private DimensionSizeIndexPair[] dimensions;

	/**
	 * @param dimensionsSizesArray - array contains lengths of every 
	 * space dimension. E.g. if we have 3 parameters (dimensions) and 
	 * each of dimensions (parameters) can be equal to any value
	 * from set {0, 1, ... , 8, 9}, then maxCountOfValuesArray should 
	 * be equal to [10, 10, 10]; Thus generator will be able to generate 
	 * all coordinates from this space.
	 * <p>
	 * Actually it will only return indexes of parameters from particular
	 * dimensions, as some of dimensions can be represented by non-numeric
	 * values (example used algorithm - different algorithms will be marked 
	 * by different indexes ) 
	 */
	public SpaceCoordinatesGenerator(Integer[] dimensionsSizesArray) {
		int dimensionsCount = dimensionsSizesArray.length;
		this.dimensions = new DimensionSizeIndexPair[dimensionsCount];
		
		for (int i = 0; i < dimensionsCount; i++) {
			DimensionSizeIndexPair maxValueIndexPair = dimensions[i];
			Integer dimensionSize = dimensionsSizesArray[i];
			maxValueIndexPair.setDimensionParameterIndex(0);
			maxValueIndexPair.setMaxDimensionParameterIndex(dimensionSize);
		}
	}
	
	/**
	 * @return Integer[] - returns next indexes of parameters.
	 */
	public Integer[] getSpaceCoordinates() {
		int dimensionsCount = dimensions.length;
		Integer[] coordinates = new Integer[dimensionsCount];
		for (int i = 0; i < dimensionsCount; i++) {
			DimensionSizeIndexPair dimensionSizeIndexPair = dimensions[i];
			Integer parameterIndex = dimensionSizeIndexPair.getDimensionParameterIndex();
			coordinates[i] = parameterIndex;
		}
		
		return coordinates;
	}
	
	public void generateNextCombination() {
		int dimensionsCount = dimensions.length;
		int dimensionIndex = 0;
		while (dimensionIndex < dimensionsCount) {
			DimensionSizeIndexPair maxValueIndexPair = dimensions[dimensionIndex];
			if (!maxValueIndexPair.isLastIndex()) {
				maxValueIndexPair.increaseIndex();
				break;
			} else {
				maxValueIndexPair.resetIndex();
			}
		}
	}
	
	/**
	 * Returns true when last combination is remaining 
	 * 
	 * @return
	 */
	public Boolean isLast() {
		Boolean isLast = Boolean.FALSE;
		
		int dimensionsCount = dimensions.length;
		DimensionSizeIndexPair lastDimensionSizeIndexPair = dimensions[dimensionsCount-1];
		Integer parameterIndex = lastDimensionSizeIndexPair.getDimensionParameterIndex();
		Integer maxParameterIndex = lastDimensionSizeIndexPair.getMaxDimensionParameterIndex();
		if (parameterIndex.equals(maxParameterIndex)) {
			isLast = Boolean.TRUE;
		}
		return isLast;
	}
}